<!--
 * @Author: your name
 * @Date: 2021-04-06 15:50:16
 * @LastEditTime: 2021-05-07 17:01:17
 * @LastEditors: Please set LastEditors
 * @Description: In User Settings Edit
 * @FilePath: /Interview Files/大纲/1112实现new.html
-->
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>实现new</title>
</head>

<body>
    <p>
        new 运算符创建一个用户定义的对象类型的实例或具有构造函数的内置对象的实例。new 关键字会进行如下的操作：
    </p>
    <ol>
        <li>创建一个空的简单 JavaScript 对象（即{}）</li>
        <li>链接该对象（即设置该对象的构造函数）到另一个对象 ；（ 通俗理解就是新对象隐式原型__proto__链接到构造函数显式原型prototype上。）</li>
        <li>将步骤 1 新创建的对象作为 this 的上下文 ；（ 实际是执行了构造函数 并将构造函数作用域指向新对象 ）</li>
        <li>如果该函数没有返回对象，则返回 this。（ 实际是返回一个空对象， new Object()就是返回一个空对象{} ）</li>
    </ol>
</body>

</html>
<script>
    function _new1(constructor, ...args) {
        let obj = {};
        obj.__proto__ = constructor.prototype;

        let res = constructor.apply(obj, args);
        return Object.prototype.toString.call(res) === '[object] [Object]' ? res : obj;

    }
    let obj = {};
    let arr = [];
    let num = 1;
    let bool = true;
    let str = 'hzt';
    let udf = undefined;
    let nul = null;
    console.log('====function========================');
    console.log(_new1.__proto__);
    console.log(_new1.prototype);
    console.log(_new1.constructor);
    console.log('====object========================');
    console.log(obj.__proto__);
    console.log(obj.prototype);
    console.log(obj.constructor);
    console.log('====array========================');
    console.log(arr.__proto__);
    console.log(arr.prototype);
    console.log(arr.constructor);
    console.log('====number========================');
    console.log(num.__proto__);
    console.log(num.prototype);
    console.log(num.constructor);
    console.log('====boolean========================');
    console.log(bool.__proto__);
    console.log(bool.prototype);
    console.log(bool.constructor);
    console.log('====string========================');
    console.log(str.__proto__);
    console.log(str.prototype);
    console.log(str.constructor);
    console.log('====undefined========================');
    // console.log(udf.__proto__);
    // console.log(udf.prototype);
    // console.log(udf.constructor);
    console.log('====null========================');
    // console.log(nul.__proto__);
    // console.log(nul.prototype);
    // console.log(nul.constructor);
    console.log('====Math========================');
    console.log(Math.__proto__);
    console.log(Math.prototype);
    console.log(Math.constructor);
    console.log('====Date========================');
    console.log(Date.__proto__);
    console.log(Date.prototype);
    console.log(Date.constructor);
    console.log('============================');
    const Fun1 = function(name) {
        this.name = name;
        console.log(this)
        console.log(Fun1.prototype == _new1.__proto__);
        // console.log(_new1.__proto__)
    }
    console.log(_new1(Fun1, 'xiaoming'))
</script>
<script>
    function _new(constructor, ...arg) {
        var obj = {}; // 对应于上面的步骤 1
        obj.__proto__ = constructor.prototype; // 对应于上面的步骤 2

        var res = constructor.apply(obj, arg); // 对应于上面的步骤 3

        return Object.prototype.toString.call(res) === '[object Object]' ? res : obj; // 对应于上面的步骤 4
    }

    const Fun = function(name) {
        this.name = name;
    };

    console.log(_new(Fun, '小明'));

    // Fun {name: "小明"}
</script>